//
//  CLCollectionViewFlowLayout.m
//  Charles
//
//  Created by Leo on 2017/4/6.
//  Copyright © 2017年 charles. All rights reserved.
//

#import "CLCollectionViewFlowLayout.h"

@interface UICollectionViewLayoutAttributes (AlignLeft)

- (void)leftAlignFrameWithSectionInset:(UIEdgeInsets)sectionInset;

@end

@implementation UICollectionViewLayoutAttributes (AlignLeft)

- (void)leftAlignFrameWithSectionInset:(UIEdgeInsets)sectionInset
{
    CGRect frame = self.frame;
    frame.origin.x = sectionInset.left;
    self.frame = frame;
}

@end


@implementation CLCollectionViewFlowLayout



/**
 允许item的实时刷新
 */
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
    return YES;
}


- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset {
    CGRect targetRect = CGRectMake(proposedContentOffset.x, 0, self.collectionView.bounds.size.width, self.collectionView.bounds.size.height);
    NSArray *attriArray = [super layoutAttributesForElementsInRect:targetRect];
    CGFloat horizontalCenterX = proposedContentOffset.x + self.collectionView.bounds.size.width/2;
    CFBit offsetAdjustment = CGFLOAT_MAX;
    for (UICollectionViewLayoutAttributes*layoutAttributes in attriArray) {
        CGFloat itemHorizontalCenterX = layoutAttributes.center.x;
        if (abs(itemHorizontalCenterX - horizontalCenterX) < abs(offsetAdjustment)) {
            offsetAdjustment = itemHorizontalCenterX - horizontalCenterX;
        }
    }
    return CGPointMake(proposedContentOffset.x + offsetAdjustment, proposedContentOffset.y);
}
/*
// 这个方法在滚动的过程当中, 系统会根据需求来调用
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
    
    // 要想计算每个cell的缩放比, 就要先计算出整体的中心点的x值 和 每个cell的中心点的x值
    // 用这两个x值做一个差值, 然后计算出绝对值, 这样就得到了每个cell的中心点的x值和整体中心点的x值之间的距离
    // 根据这个距离就可以计算出一个缩放比
    
    // 1. 先计算出整体的中心点的x值
    CGFloat centerX = self.collectionView.contentOffset.x + self.collectionView.bounds.size.width * 0.5;
    
    // 在这个方法中, 我们只要根据当前的滚动, 对每个cell, 进行对应的缩放就可以了
    
    // 1. 获取所有的attributes对象
    NSArray *arrayAttrs = [super layoutAttributesForElementsInRect:rect];
    
    // 2. 循环遍历这些attributes对象, 对每个对象进行缩放
    for (UICollectionViewLayoutAttributes *attr in arrayAttrs) {
        
        // 获取每个cell的中心点的x值
        CGFloat cell_centerX = attr.center.x;
        
        // 计算这两个中心点的x值的偏移（距离）
        CGFloat distance = ABS(cell_centerX - centerX);
        
        // 如何根据这个距离计算缩放比?
        // 距离越大, 缩放比应该越小。 距离越小缩放比越大。缩放比最大是1.当两个中心点的x值相等的时候（重合），此时缩放比就是1.
        
        // 缩放系数
        CGFloat factor = 0.003;
        // 记录缩放比
        CGFloat scale = 1 / (1 + distance * factor);
        attr.size = CGSizeMake(self.itemSize.width * 1.5, self.itemSize.height * 1.5);
        attr.transform = CGAffineTransformMakeScale(scale, scale);
        //        attr.transform = CGAffineTransformTranslate(attr.transform, 100, 0);
        
    }
    // 3. 返回修改后的attributes数组
    return arrayAttrs;
}
*/

@end

@implementation SRCollectionViewLeftFlowLayOut

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
    NSArray *originalAttributes = [super layoutAttributesForElementsInRect:rect];
    NSMutableArray *updatedAttributes = [NSMutableArray arrayWithArray:originalAttributes];
    for (UICollectionViewLayoutAttributes *attributes in originalAttributes) {
        if (!attributes.representedElementKind) {
            NSUInteger index = [updatedAttributes indexOfObject:attributes];
            updatedAttributes[index] = [self layoutAttributesForItemAtIndexPath:attributes.indexPath];
        }
    }
    return updatedAttributes;
}

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
    UICollectionViewLayoutAttributes* currentItemAttributes = [[super layoutAttributesForItemAtIndexPath:indexPath] copy];
    UIEdgeInsets sectionInset = [self evaluatedSectionInsetForItemAtIndex:indexPath.section];
    
    BOOL isFirstItemInSection = indexPath.item == 0;
    CGFloat layoutWidth = CGRectGetWidth(self.collectionView.frame) - sectionInset.left - sectionInset.right;
    
    if (isFirstItemInSection) {
        [currentItemAttributes leftAlignFrameWithSectionInset:sectionInset];
        return currentItemAttributes;
    }
    
    NSIndexPath* previousIndexPath = [NSIndexPath indexPathForItem:indexPath.item-1 inSection:indexPath.section];
    CGRect previousFrame = [self layoutAttributesForItemAtIndexPath:previousIndexPath].frame;
    CGFloat previousFrameRightPoint = previousFrame.origin.x + previousFrame.size.width;
    CGRect currentFrame = currentItemAttributes.frame;
    CGRect strecthedCurrentFrame = CGRectMake(sectionInset.left,
                                              currentFrame.origin.y,
                                              layoutWidth,
                                              currentFrame.size.height);
    // if the current frame, once left aligned to the left and stretched to the full collection view
    // widht intersects the previous frame then they are on the same line
    BOOL isFirstItemInRow = !CGRectIntersectsRect(previousFrame, strecthedCurrentFrame);
    
    if (isFirstItemInRow) {
        // make sure the first item on a line is left aligned
        [currentItemAttributes leftAlignFrameWithSectionInset:sectionInset];
        return currentItemAttributes;
    }
    
    CGRect frame = currentItemAttributes.frame;
    frame.origin.x = previousFrameRightPoint + [self evaluatedMinimumInteritemSpacingForSectionAtIndex:indexPath.section];
    currentItemAttributes.frame = frame;
    return currentItemAttributes;
}

- (CGFloat)evaluatedMinimumInteritemSpacingForSectionAtIndex:(NSInteger)sectionIndex
{
    if ([self.collectionView.delegate respondsToSelector:@selector(collectionView:layout:minimumInteritemSpacingForSectionAtIndex:)]) {
        id<SRCollectionViewLeftDelegateFlowLayout> delegate = (id<SRCollectionViewLeftDelegateFlowLayout>)self.collectionView.delegate;
        
        return [delegate collectionView:self.collectionView layout:self minimumInteritemSpacingForSectionAtIndex:sectionIndex];
    } else {
        return self.minimumInteritemSpacing;
    }
}

- (UIEdgeInsets)evaluatedSectionInsetForItemAtIndex:(NSInteger)index
{
    if ([self.collectionView.delegate respondsToSelector:@selector(collectionView:layout:insetForSectionAtIndex:)]) {
        id<SRCollectionViewLeftDelegateFlowLayout> delegate = (id<SRCollectionViewLeftDelegateFlowLayout>)self.collectionView.delegate;
        
        return [delegate collectionView:self.collectionView layout:self insetForSectionAtIndex:index];
    } else {
        return self.sectionInset;
    }
}


@end

@implementation CLCollectionViewPageFlowLayOut

- (void)prepareLayout {
    [super prepareLayout];
}

/**
 滚动停止时，滚动慢慢停止并停留在某一个item上的效果
 */
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity {
    CGRect fr = self.collectionView.bounds;
    CGFloat halfWidth = fr.size.width * 0.5f;
    CGFloat proposedContentOffsetCenterX = proposedContentOffset.x + halfWidth;
    NSArray* attributesArray = [self layoutAttributesForElementsInRect:fr];
    UICollectionViewLayoutAttributes* candidateAttributes;
    for (UICollectionViewLayoutAttributes* attributes in attributesArray) {
        if (attributes.representedElementCategory !=
            UICollectionElementCategoryCell) {
            continue;
        }
        if(!candidateAttributes) {
            candidateAttributes = attributes;
            continue;
        }
        if (fabs(attributes.center.x - proposedContentOffsetCenterX) <
            fabs(candidateAttributes.center.x - proposedContentOffsetCenterX)) {
            candidateAttributes = attributes;
        }
    }
    return CGPointMake(candidateAttributes.center.x - halfWidth, proposedContentOffset.y);
}

/**
 允许item的实时刷新
 */
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
    return YES;
}
@end
